﻿using DesignModeConsole.行为型.职责链模式.抽取试题;

namespace DesignModeConsole.行为型.职责链模式;

/// <summary>
/// 职责链模式
/// </summary>
public class ChainResponsibilityService : IService
{
    public void Main()
    {
        #region 依次检查，遇到可以处理的时候，就不往下传递请求了

        //// 职责链模式方法一  使用链表的方式去处理
        //var chain = new HandlerChain1_2();
        //chain.AddHandler(new Handler1A1_2());
        //chain.AddHandler(new Handler1B1_2());
        //chain.Handle();

        //// 职责链模式方案2 使用数组的方式去处理
        //var chain2 = new HandlerChain2();
        //chain2.AddHandler(new Handler2A());
        //chain2.AddHandler(new Handler2B());
        //chain2.Handle();

        #endregion

        #region 依次处理，处理后不返回

        //// 链表方式实现
        //var chain3 = new HandlerChain3();
        //chain3.AddHandler(new HandlerA3());
        //chain3.AddHandler(new HandlerB3());
        //chain3.Handle();

        //// 数组方式实现
        //var chain4 = new HandlerChain4();
        //chain4.AddHandler(new Handler4A());
        //chain4.AddHandler(new Handler4B());
        //chain4.Handle();

        #endregion

        // 试题抽取
        GetExamList().GetAwaiter().GetResult();
    }

    /// <summary>
    /// 试题抽取方法
    /// </summary>
    private async Task GetExamList()
    {
        var examLib = new List<ExtractExamAbstractHandler>
        {
            new ChineseExamHandler(),
            new MathematicsExamHandler(),
            new EnglishExamHandler()
        };

        // 设置开始
        var firstHandler = examLib[0];
        // 移除第一个
        examLib.RemoveAt(0);
        foreach (var exam in examLib)
        {
            SetNextHandler(firstHandler, exam);
        }

        // 抽题设置
        var flowDto = new ExtractExamFlowDto
        {
            TotalCount = 4,
            UserId = "10"
        };
        var examList = (await firstHandler.HandlerAsync(flowDto)).ExamList;
        await Console.Out.WriteLineAsync($"已经成功抽取{examList.Count}题，分别是：{string.Join(",", examList)}");
    }

    /// <summary>
    /// 递归设置职责链流程
    /// </summary>
    /// <param name="handler"></param>
    /// <param name="nextHandler"></param>
    private void SetNextHandler(ExtractExamAbstractHandler handler, ExtractExamAbstractHandler nextHandler)
    {
        // 如果当前
        if (handler.NextHandler is not null)
        {
            SetNextHandler(handler.NextHandler, nextHandler);
            return;
        }

        handler.NextHandler = nextHandler;
    }
}